/**
 * Created by Administrator on 2017/1/15.
 */

var config = require('./config');

var MJ = require('../MJ/MJ');
var MJRoom = require('../MJ/room').MJRoom;

var Const = require('./const');
var SubCode = require('../subCode');

exports.XZMJRoom = MJRoom.extend({

    _hszStatus: 0,            // 换三张状态
    _maCard: 0,               // 买马的牌,0未买马

    init: function(rid, creator, msg) {
        this._super(rid, creator, msg);
        this._hszStatus = Const.HSZStatus.NONE;
        this._maCard = 0;
        this.setSaveReplay(true);
    },

    checkInit: function() {
        return this._super();
    },

    calcMaIndex: function() {
        if (!this._maCard) {
            return 0;
        }

        var maIndex = (MJ.getPoint(this._maCard) + this._dealerIndex - 1) % this.getMaxPlayer();
        if (maIndex == 0) {
            maIndex = this.getMaxPlayer();
        }

        return maIndex;
    },

    /******************************************************************
     * 重载的接口
     ******************************************************************/

    getRoomConfig: function() {
        var cfg = this._super();
        cfg.destroyWaitTime = 300;
        cfg.respDestroyIgnoreOffline = false;
        return cfg;
    },

    getReconnectInfo: function(rePlayer) {
        var info = this._super(rePlayer);
        info.hszStatus = this._hszStatus;
        info.maCard = (this._maCard) ? 1 : 0; //是否已买马
        return info;
    },

    onBeforeStartNewRound: function() {
        this._super();
        this._hszStatus = Const.HSZStatus.NONE;
        this._maCard = 0;
    },

    onAfterStartNewRound: function() {
        this._super();
        this.initPlayersHandCards();

        // 操作流程：庄家买马 => 换三张 => 定缺
        if (!this.getOption("MA") && !this.getOption("HSZ") && !this.isSelectColor()) {
            this.startPlay();
        }
    },

    startPlay: function() {
        this._startPlay();
    },

    _startPlay: function() {
        this._changeCurPlay(this.getDealerIndex());
        this._doCheckNewCardHangupTask();
    },

    onBeforePlayCard: function(player, msg, card) {
        var code = this._super(player, msg, card);
        if (code) {
            return code;
        }

        if (this.getOption("MA") && !this._maCard) {
            return SubCode.XZMJ_MA_NOT_SELECT;
        }

        if (this.getOption("HSZ") && this._hszStatus != Const.HSZStatus.FINISHED) {
            return SubCode.MJ_HSZ_STATUS_ERROR;
        }

        if (player.isBaoTing() && card != player.getLastCard()) { //天听不能换牌
            return SubCode.MJ_IS_BAOTING;
        }
    },

    checkNewCardHangupTask: function() {
        var player = this.getCurPlayer();

        var huIndexs = [];
        var huPattern = player.checkHu();
        if (huPattern != Const.Pattern.NONE) {
            var rules = [];
            if (this.getCurGang()) {
                rules.push(Const.ScoreRule.GSH);
            }

            if (this.getOption("TDH")) {
                if (player.isFirstHand()) {
                    rules.push((player.getIndex() == this.getDealerIndex()) ? Const.ScoreRule.TH : Const.ScoreRule.DIHU);
                }
            }

            var card = player.getLastCard() || player.getInitLastCard();
            this._hangupTask.addHuTask(player.getIndex(), card, player.getIndex(), huPattern, rules);
            huIndexs.push(player.getIndex());
        }

        var gangArray = player.checkGang();
        if (gangArray.length > 0) {
            var gangTask = null;
            if (!player.isBaoTing()) {
                gangTask = gangArray[0];
            } else {
                for (var i = 0; i < gangArray.length; ++i) {
                    if (!player.checkTingChangeIfGang(gangArray[i])) {
                        gangTask = gangArray[i]; break;
                    }
                }
            }
            if (gangTask) {
                this._hangupTask.addGangTask(player.getIndex(), gangTask);
            }
        }

        if (this.getPublicCards().getRemainNum() <= 4) {
            huIndexs.forEach(function(eIndex) {
                this._hangupTask.submitTaskWithoutCheck(eIndex, MJ.Task.HU);
            }.bind(this));
        }
    },

    checkPlayCardHangupTask: function(card) {

        var curPlay = this.getCurPlay();
        var huIndexs = [];

        this.enumPlayers(function(eIndex, ePlayer) {
            if (eIndex != curPlay && !ePlayer.isRoundHu()) {
                if (!ePlayer.isPassHu() && ePlayer.getBaoTingPassHuTimes() < 1) {
                    var huPattern = ePlayer.checkHuWithCard(card);
                    if (huPattern != Const.Pattern.NONE) {
                        var rules = [];

                        if (this.getCurGang() > 0) {
                            rules.push(Const.ScoreRule.GSP);
                        }

                        var enableHu = false;
                        if (this.getOptionEx("KXH") || (huPattern != Const.Pattern.NORMAL) || (rules.length > 0)) {
                            enableHu = true;
                        } else {
                            if (!ePlayer.isXH(card)) {
                                enableHu = true;
                            }
                        }

                        if (enableHu) {
                            this._hangupTask.addHuTask(ePlayer.getIndex(), card, curPlay, huPattern, rules);
                            huIndexs.push(eIndex);
                        }
                    }
                }

                if (ePlayer.checkPengWithCard(card)) {
                    this._hangupTask.addPengTask(eIndex, card, curPlay);
                }

                if (ePlayer.checkGangWithCard(card)) {
                    var gangTask = {card: card, from: curPlay, gang: MJ.Gang.DIAN};
                    if (!ePlayer.isBaoTing() || !ePlayer.checkTingChangeIfGang(gangTask)) {
                        this._hangupTask.addGangTask(eIndex, gangTask);
                    }
                }
            }
        }.bind(this));

        if (this.getPublicCards().getRemainNum() <= 4) {
            huIndexs.forEach(function(eIndex) {
                this._hangupTask.submitTaskWithoutCheck(eIndex, MJ.Task.HU);
            }.bind(this));
        }
    },

    checkGangHangupTask: function(playerIndex, gangInfo) {
        var card = gangInfo.card;
        var huIndexs = [];
        this.enumPlayers(function(eIndex, ePlayer) {
            if (eIndex != playerIndex && !ePlayer.isRoundHu() && !ePlayer.isPassHu() && ePlayer.getBaoTingPassHuTimes() < 1) {
                var huPattern = ePlayer.checkHuWithCard(card);
                if (huPattern != Const.Pattern.NONE) { // 抢杠
                    var rules = [];
                    rules.push(Const.ScoreRule.QG);

                    this._hangupTask.addHuTask(eIndex, card, playerIndex, huPattern, rules);
                    huIndexs.push(eIndex);
                }
            }
        }.bind(this));

        if (this.getPublicCards().getRemainNum() <= 4) {
            huIndexs.forEach(function(eIndex) {
                this._hangupTask.submitTask(eIndex, MJ.Task.HU);
            }.bind(this));
        }
    },

    checkGangTaskQG: function(task, gangInfo) {
        return gangInfo.gang == MJ.Gang.BA;
    },

    checkHuSettlement: function() {
        return this.getHuPlayerCount() >= (this.getPlayingPlayerCount() - 1);
    },

    onSettlementHuTask: function(task) {
        var playerIndex = task.playerIndex;
        var pattern = task.pattern;
        var card = task.card;
        var from = task.from;
        var rules = task.rules;
        var huPlayer = this.getPlayerByIndex(playerIndex);

        var isZM = (playerIndex == from); // 是否是自摸

        var targetsIndex = [];
        var targets = [];
        if (isZM) {
            this.enumPlayers(function(eIndex, ePlayer) {
                if (eIndex != playerIndex && !ePlayer.isRoundHu()) {
                    targetsIndex.push(eIndex);
                    targets.push(ePlayer);
                }
            });
        } else {
            targetsIndex.push(from);
            targets.push(this.getPlayerByIndex(from));
        }

        var patternScore = Const.PatternScore[pattern];

        for (var i = 0; i < rules.length; ++i) {
            var rule = rules[i];
            switch (rule) {
                case Const.ScoreRule.QG:
                    if (!isZM) {
                        var targetPlayer = targets[0];
                        if (targetPlayer.getIndex() == this.getCurPlay() && this.getCurGang() > 0) { // 抢杠的被抢玩家一定是当前玩家
                            huPlayer.setRoundScoreRule(rule);
                            huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);

                            targetPlayer.setRoundScoreRule(rule);
                            targetPlayer.cancelLastGangForQG(card);
                        }
                    }
                    break;
                case Const.ScoreRule.GSP:
                    if (!isZM) {
                        huPlayer.setRoundScoreRule(rule);
                        huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
                        if (!task.YPDX) {
                            targets[0].transLastGangTo(huPlayer.getIndex());
                        }
                    }
                    break;
                case Const.ScoreRule.GSH:
                    huPlayer.setRoundScoreRule(rule);
                    huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
                    break;
                case Const.ScoreRule.TH:
                    huPlayer.setRoundScoreRule(rule);
                    huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
                    break;
                case Const.ScoreRule.DIHU:
                    huPlayer.setRoundScoreRule(rule);
                    huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
                    break;
                default:
                    break;
            }
        }

        huPlayer.setRoundResult(isZM ? MJ.Result.ZM : MJ.Result.DH, targetsIndex, card);
        huPlayer.setRoundPattern(pattern, patternScore);
        huPlayer.settlementRules();

        this.broadcastReplay("onPlayerHu", {
            playerIndex: playerIndex,
            card: card,
            from: from,
        });
    },

    onSettlement: function() {
        this.enumPlayers(function(eIndex, ePlayer) {
            this._settlementPlayerTing(ePlayer);
        }.bind(this));

        this.enumPlayers(function(eIndex, ePlayer) {
            ePlayer.settlementGangScore();
            ePlayer.settlementPatternScore();
        }.bind(this));

        // 至少有两家未胡牌时查听（叫）
        if (this.getPlayerCount() - this.getHuPlayerCount() >= 2) {
            this.enumPlayers(function(eIndex, ePlayer) {
                ePlayer.settlementTingScore();
            }.bind(this));
        }
    },

    getSettlementInfo: function() {
        var info = this._super();
        info.maCard = this._maCard;
        return info;
    },

    onCurRoundFinished: function() {
        this._super();

        // 计算新的庄家
        var newDealerIndex = 0;
        if (!this.isRoundHZ()) {
            this.enumPlayers(function(eIndex, ePlayer) {
                if (ePlayer.existRoundScoreRule(Const.ScoreRule.YPDX)) {
                    newDealerIndex = eIndex;
                }
            });

            if (!newDealerIndex) {
                newDealerIndex = this.getFirstHuPlayerIndex();
            }
        } else {
            newDealerIndex = this._curPlay;
        }

        if (newDealerIndex != this._dealerIndex) {
            this._dealerIndex = newDealerIndex;
            this._dealerLZ = 1;
        } else {
            this._dealerLZ++;
        }

        this.broadcastReplay("onDealerChanged", {
            dealer: this._dealerIndex,
            dealerLZ: this._dealerLZ
        });
    },

    /******************************************************************
     * 消息处理
     ******************************************************************/

    /**
     * 庄家买马
     * @param player
     * @param msg {}
     * @param callback
     */
    handleSelectMaCard: function(player, msg, callback) {
        if (!this.isPlaying()) {
            callback({code: Code.ROOM_NOT_PLAYING}); return;
        }

        if (!this.getOption("MA")) {
            callback({code: SubCode.XZMJ_MA_NOT_ALLOWED}); return;
        }

        if (!player.isDealer()) {
            callback({code: SubCode.MJ_PLAYER_NOT_DEALER}); return;
        }

        if (this._maCard) {
            callback({code: SubCode.XZMJ_MA_SELECTED}); return;
        }

        this._maCard = this._publicCards.lookCard();//MJ.getValue(MJ.Color.TIAO, 3);
        callback({});

        this.broadcastReplay("onMaCardSelected", {});

        if (!this.getOption("HSZ") && !this.isSelectColor()) {
            this.startPlay();
        }
    },

    /**
     * 换三张
     * @param player
     * @param msg {cards:[]}
     * @param callback
     */
    handleSelectHSZ: function(player, msg, callback) {
        if (!this.isPlaying()) {
            callback({code: Code.ROOM_NOT_PLAYING}); return;
        }

        if (!this.getOption("HSZ")) {
            callback({code: SubCode.MJ_HSZ_NOT_ALLOWED}); return;
        }

        if (this.getOption("MA") && !this._maCard) {
            callback({code: SubCode.XZMJ_MA_NOT_SELECT}); return;
        }

        var cards = msg.cards;
        if (!cards || !(cards instanceof Array) || cards.length != 3) {
            callback({code: Code.ARGS_INVALID}); return;
        }

        if (this._hszStatus != Const.HSZStatus.NONE) {
            callback({code: SubCode.MJ_HSZ_STATUS_ERROR}); return;
        }

        var code = player.selectHSZCards(cards);
        if (code != Code.SUCCESS) {
            callback({code: code}); return;
        }

        callback({});

        this.broadcast("onPlayerSelectHSZ", {
            playerIndex: player.getIndex(),
        });

        this.addRoundReplay("onPlayerSelectHSZ", {
            playerIndex: player.getIndex(),
            cards: cards
        });

        var isAllSelected = true;
        this.enumPlayers(function(eIndex, ePlayer) {
            if (ePlayer.getSelectedHSZCards().length != 3) {
                isAllSelected = false;
            }
        });

        if (isAllSelected) {
            this.enumPlayers(function(eIndex, ePlayer) {
                var exchangeIndex = this.getNextIndex(eIndex);
                ePlayer.exchangeHSZCards(this.getPlayerByIndex(exchangeIndex).getSelectedHSZCards());
            }.bind(this));

            this._hszStatus = Const.HSZStatus.FINISHED;
            this.broadcastReplay("onRoomHSZFinished", {});

            if (!this.isSelectColor()) {
                this.startPlay();
            }
        }
    },

    /******************************************************************
     * 功能接口
     ******************************************************************/

    /**
     * 结算玩家是否听牌
     * @param player
     * @private
     */
    _settlementPlayerTing: function(player) {
        //已听牌玩家不用再检测
        if (player.isRoundTing()) {
            return;
        }

        // 对未胡牌的玩家检查是否听牌
        var tings = player.checkTing();
        var pattern = Const.Pattern.NONE;
        var patternScore = -1;
        var patternRules = null;

        for (var i = 0; i < tings.length; ++i) {
            var ting = tings[i];

            var rules = player.settlementTingRules(ting.pattern, ting.card);
            var score = Const.PatternScore[ting.pattern] + ExObject.sumValue(rules);
            if (score > patternScore) {
                pattern = ting.pattern;
                patternScore = score;
                patternRules = rules;
            }
        }

        player.setRoundPattern(pattern, 0);
        player.setTingRules(patternRules);
    },
});